package com.activenetwork.custom.other;

import java.util.List;
import java.util.regex.Pattern;


import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

import com.activenetwork.util.EnvContext;

public class XSelectList implements SelectList {
	private WebDriver driver;
	private WebElement element;
	
	public XSelectList(WebElement element){
		this.element = element;
		//TODO: what if thread local is empty for get a webdriver
		this.driver = EnvContext.webDriverTL.get();
	}

	@Override
	public void clear() {
		element.clear();
	}

	@Override
	public void click() {
		element.click();
	}

	@Override
	public WebElement findElement(By by) {
		return element.findElement(by);
	}

	@Override
	public List<WebElement> findElements(By by) {
		return element.findElements(by);
	}

	@Override
	public String getAttribute(String attr) {
		return element.getAttribute(attr);
	}

	@Override
	public String getCssValue(String css) {
		return element.getCssValue(css);
	}

	@Override
	public Point getLocation() {
		return element.getLocation();
	}

	@Override
	public Dimension getSize() {
		return element.getSize();
	}

	@Override
	public String getTagName() {
		return element.getTagName();
	}

	@Override
	public String getText() {
		return element.getText();
	}

	@Override
	public boolean isDisplayed() {
		return element.isDisplayed();
	}

	@Override
	public boolean isEnabled() {
		return element.isEnabled();
	}

	@Override
	public boolean isSelected() {
		return element.isSelected();
	}

	@Override
	public void sendKeys(CharSequence... chars) {
		element.sendKeys(chars);
	}

	@Override
	public void submit() {
		element.submit();
	}

	@Override
	public WebElement getEmbedElement() {
		return element;
	}

	@Override
	public void select(String... options) {
		List<WebElement> items = element.findElements(By.xpath("./option"));
		
		Actions actions = new Actions(driver);
		actions.keyDown(Keys.CONTROL);
		for(String option : options){			
			for(WebElement item : items){
				String optionValue = item.getText().trim();
				if(StringUtils.equals(option, optionValue)){
					item.click();
				}
			}
		}
		actions.keyUp(Keys.CONTROL);
		//TODO: what if the option can not be found in multi select
	}

	@Override
	public void select(int... options) {
		for(int option : options){
			if(option - 1 < 0){
				throw new RuntimeException("All the options must be larger than 0.");
			}
		}
		List<WebElement> items = element.findElements(By.xpath("./option"));
		Actions actions = new Actions(driver);
		actions.keyDown(Keys.CONTROL);
		for(int option: options){
			items.get(option-1).click();
		}
		actions.keyUp(Keys.CONTROL);
	}

	@Override
	public void select(Pattern... options) {
		List<WebElement> items = element.findElements(By.xpath("./option"));
		Actions actions = new Actions(driver);
		actions.keyDown(Keys.CONTROL);
		for(Pattern option : options){
			for(WebElement item : items){
				String optionValue = item.getText().trim();
				if(option.matcher(optionValue).matches()){
					item.click();
				}
			}
		}
		actions.keyUp(Keys.CONTROL);	
	}

}
